(for Internet Explorer)
Dim  a : Set a = new ArrayClass
a.Add  "abc"
a.Add  "def"

echo  a.CSV '// "abc,def"
CSV
関連
サンプル
Assert  new_ArrayClass( Array( 1, 2, 3 ) ).CSV = "1,2,3"
サンプル
Dim  a : Set a = new ArrayClass
a.Add  "abc"
a.Add  "def"

echo  a.Code '// [ "abc","def" ]と表示
サンプル
→ vbslib.vbs
→ T_Arr.vbs
テスト
ソース
T_ArrClass_Code
Dim  a
Set a = New ArrayClass
a.Add  1
a.Copy  Array( 2, 3 )
'// a は、{ 2, 3 }
Copy
(src)
Set  arr = new ArrayClass
s = GetEchoStr( arr )
次のように代用できます。
Set  arr = new ArrayClass
echo  arr
次のように代用できます。
の要素を順番にたどっていくクラスです。
Dim  a : Set a = new ArrayClass
Dim  iter : Set iter = a.NewIterator()
While iter.HasNext()
  echo  iter.GetNext()
WEnd
サンプル
メンバー
参考
→ イテレーター (JavaScript 1.7)
次の要素を返す。 次回の呼び出しでは、その次の要素を返す。
次の要素があるかどうか
取得
(src)
次の要素を返す。 次の要素が無いときは、番兵を返す。
テスト
→ T_Arr_Target # [T_ArrIter]
Function  ArrayClassIterator::GetNext() as variant
次の要素を返す。 次回の呼び出しでは、その次の要素を返す。
Java2 の Iterator パターン、JavaScript 1.7 のイテレーターでは、next に相当します。
Next は、VB言語の予約語であることと、Me に副作用があるため、プロパティではなくメソッド
であり、メソッドは動詞で始まる方が読みやすいため、GetNext に変更しています。
補足
次の要素が無いときは、エラーになります。 エラーにしたくないときは、
を使ってください。
Function  ArrayClassIterator::HasNext() as boolean
次の要素があるかどうかを返す。
  Dim  f, line, a, elem, iter
  Set a = new ArrayClass : a.Add  new Elem
  Set iter = a.NewIterator
  Set sentinel = new Elem
  Set elem = iter.GetNextOrSentinel( sentinel )

  Set f = OpenForRead( path )
  Do Until  f.AtEndOfStream
    line = f.ReadLine()
    If elem.IsMatch( line ) Then  '// ここで番兵が使われることがある
      ...
      elem = iter.GetNextOrSentinel( sentinel )
              '// GetNext ではここでエラーになってしまうことがある
    End If
  Loop
  f = Empty
  elem = Empty
  iter = Empty
Function  ArrayClassIterator::GetNextOrSentinel( Sentinel as variant ) as variant
次の要素を返す。 ただし、次の要素が無いときは、Sentinel 引数(番兵)を返す。
サンプル:
GetNextOrSentinel
GetNextOrSentinel
標準の
の Item を、配列にしたクラスです。
  Dim  dic

  Set dic = new ArrayDictionary
  dic.Add  "key1", "item11"
  dic.Add  "key1", "item12"
  dic.Add  "key1", "item13"
  dic.Add  "key2", "item21"
  dic.Echo

  Dim  i,j
  For Each j in dic.Dic.Items() : For Each i in j.Items
    WScript.Echo  i
  Next : Next
item11
item12
item13
item21
上記スクリプトの出力
サンプル:
VBScript 標準の Dictionary (プロパティ)
メンバ
キーに要素を登録する。キーは重複可能
すべての要素を削除します
すべての要素を表示する
要素の数
1つのキーに対して、複数のアイテムを関連付けするときに使います。
(src)
テスト
→ T_Arr_Target.vbs [T_ArrayDic1]
Key, Item
*
Item
*
Dim  ArrayDictionary::Dic  as Dictionary of variant
ArrayDictionary クラスがラップしている辞書です。
要素(Item)は、オブジェクトでもそれ以外でも格納します。
(src)
Sub  ArrayDictionary::ToEmpty()
辞書に要素を空にします。 要素数は 0 になります。
(src)
Sub  ArrayDictionary::Add( Key as string, Item as variant )
辞書に要素を追加します。
Item
(src)
Function  ArrayDictionary::Count() as integer
辞書の要素数を返します。
1つのキーに複数の要素が関連付けされることがあるので、
要素数はキーの数と一致しないことがあります。
(src)
Sub  ArrayDictionary::Echo()
辞書のすべての要素を表示します。
(src)
重複しないでオブジェクトをまとめるコレクション。
Set  objects = new ObjectSetClass
Set  a_object = new NameOnlyClass
Set  b_object = new NameOnlyClass

objects.Add  a_object
objects.Add  b_object
objects.Add  b_object

echo  objects.Count  '// 2

objects.Remove  b_object

echo  objects.Count  '// 1
サンプル
テスト
ソース
→ T_Dic.vbs
T_ObjectSetClass
→ vbslib.vbs
関連
Sub  ObjectSetClass::Add( Object as variant )
コレクションに追加されていなければ、コレクションに追加します。
【引数】
Object
追加するオブジェクト
Property Get  ObjectSetClass::Count()
コレクションに追加されているオブジェクトの数を返します。
【引数】
返り値
コレクションに追加されているオブジェクトの数
Property Get  ObjectSetClass::Items()
For 文に指定できるオブジェクトの集合を返します。
Function  ObjectSetClass::Exists( Object as variant ) as boolean
コレクションに追加されているかどうかを返します。
Sub  ObjectSetClass::Remove( Object as variant )
コレクションに追加されていれば、コレクションから除外します。
【引数】
Object
除外するオブジェクト
Sub  ObjectSetClass::RemoveAll()
コレクションからすべてのオブジェクトを除外します。
g("${RootPath}") = "${${Target}/RootPath}"
g("${TargetA/RootPath}") = "C:\FolderA"
g("${TargetB/RootPath}") = "C:\FolderB"

g("${Target}") = "TargetA"
Assert  g("${RootPath}") = "C:\FolderA"
g("${Target}") = "TargetB"
Assert  g("${RootPath}") = "C:\FolderB"
g("${RootPath}") = "C:\FolderA"
Assert  g("${RootPath}") = "C:\FolderA"
元々、下記のように使われていた変数 ${RootPath} があるとします。
変数の値を、別の変数の値によって動的に変えたい場合は、下記のどちらの記述もできます。
g("${RootPath}") = "C:\Folder${Target}"

g("${Target}") = "A"
Assert  g("${RootPath}") = "C:\FolderA"
g("${Target}") = "B"
Assert  g("${RootPath}") = "C:\FolderB"
g("$\{") = "${"   '// $\ は $ に置き換わります
g("$\\") = "$\"
g("$\}") = "$}"
g("$A")  = "$A"   '// $ の後に { がないと、そのまま
(メモ) このエスケープにより、単純に "${" を検索すれば、それが展開すべき変数かどうかが
分かります。
辞書の値に、辞書のキーへの参照を入れて、遅延評価する辞書です。
LazyDictionaryClass のオブジェクトは名前空間に相当し、キーは変数名に相当します。
Set g = new LazyDictionaryClass
g("${RootPath}") = "C:\Folder${Target}"
g("${Target}") = "A"

Assert  g("${RootPath}") = "C:\FolderA"
キーは、${ 〜 } 形式(例: ${A})にしてください。 $〜 形式(例: $A)は、エラーになります。
キーの ${ 〜 } の中に "$", "{", "}" は使えませんが、他の記号、Unicode文字(日本語など)
は使えます。
g("${RootPath( TargetA )}") = "C:\FolderA"
g("${RootPath( TargetB )}") = "C:\FolderB"

target = "TargetA"
Assert  g("${RootPath( "+ target +" )}") = "C:\FolderA"
単純な変換関数であれば、関数をデータに置き換えることもできます。
下記の RootPath が、関数の代わりです。
キーが存在しなければ、エラーになります。
テスト
ソース
→ vbslib.vbs
Set g = new LazyDictionaryClass

g("${Array1}") = Array( "${Var}/1", "${Var}/2" )
g("${Array2}") = Array( "${Array1}", "${Var}/3", "${Var}/4", "${Var}/5" )
g("${Var}") = "x"
array1 = g("${Array1}")
array2 = g("${Array2}")

Assert  IsSameArray( array1, Array( "x/1", "x/2" ) )
Assert  IsSameArray( array2, Array( "x/1", "x/2", "x/3", "x/4", "x/5" ) )

For Each  value  In g("${Array2}")
    echo  value
Next
関連
g("${Var}") = True
Assert  g("${Var}") = True            '// 式ではないので boolean 型のまま
Assert  g("Var=${Var}") = "Var=True"  '// 式なので文字列に変換
式を参照すると、文字列になります。 式とは、${ } で囲まれた変数以外の文字がある文字列です。
キーの展開は参照時( g("${Var}") を Get するとき)に行われる(遅延評価である)ため、
キーを含むアイテム(値)を設定するときに、そのキーが定義されていなくても構いません。
例:上記 ${Target}。 つまり、連続して設定するときは、設定する順番を問いません。
参照時にキーが存在しないときは、エラーになります。 簡単な文字列変換関数なら、
辞書のデータに置き換えることができます。
→ 関数型プログラミング
Set g = new LazyDictionaryClass

g("${Workspace/Lib}")    = "FolderA"
g("${Workspace/Sample}") = "FolderB"

values1 = g.Each_( "${Workspace/${i}}", "${i}", Array( "Lib", "Sample" ) )
Assert  IsSameArray( values1, Array( "FolderA", "FolderB" ) )

formulas = g.EachFormula( "${Workspace/${i}}", "${i}", Array( "Lib", "Sample" ) )
Assert  IsSameArray( formulas, Array( "${Workspace/Lib}", "${Workspace/Sample}" ) )

values2 = g( formulas )
Assert  IsSameArray( values2, values1 )
Each_ や EachFormula を使えば、配列の要素をループ変数のように扱って変換できます。
また、辞書を参照するときに、配列を指定することもできます。
値( = の右)に配列を指定することができます。
また、配列の要素に、配列を値を持つ変数への参照を指定すると、ネストしないで展開されます。
$\{ と書くと、${ という文字列データができます。 この処理は、変数の展開をしないために、
最後に行われます。 展開した結果に $\ があるときは、$ に置き換わります。
→ T_LazyDictionary.vbs
オブジェクトの設定と参照ができます。
Set g("${Var}") = new NameOnlyClass
echo  g("${Var}").Name
キーが存在しないときに自動的にキーを追加しないため、文字列のスペルミスを防ぐことができます。
ただし、キーとアイテムが異なることが一般的である辞書型では、アイテムを調べなければ
文字列を知ることができないため、開発効率が落ちます。
そこで、キーの先頭が ">" から、アイテムと同じであるようなルールにするとよいでしょう。
なお、> を選んだ理由は、メールの引用(コピー)記号や、NaturalDocs の空白を維持する記号に
近い意味を持っているからです。
Set g = new LazyDictionaryClass
g("${>Spell}") = "Spell"
Set g = new LazyDictionaryClass
g("${Var1}") = "Value1"
g("${Var2}") = "${Var1}-2"

g.EchoToEditor
EchoToEditor
${Var1} = "Value1"
${Var2} = "${Var1}-2" = "Value1-2"
EchoToEditor メソッドを呼び出すと、アイテムのキーと展開前の値と展開後の値が書かれた
テキスト エディターが開きます。 内容は、GetSetListString の返り値と同じです。
テキスト エディターで開く内容:
patch_path = g("${Repository_workspace}\Sample_Test_patch\patch")
辞書を参照するコードが長くなるときは、役割を説明する説明変数をローカルで(関数内のスコープ
をもつ変数を)活用するとよいでしょう
→ 説明変数
参考
g.DebugMode = True  '// [TODO] 追加
g("${Target}") = "B"
echo  g("${RootPath}")
下記のように、デバッグ・モードをオンにすると、設定した内容を echo 表示したり、参照時にキーを
1つずつ展開する様子を echo 表示します。
<DictionaryEx operation="Set" key="${Target}">B</DictionaryEx>
<DictionaryEx operation="Get" key="${RootPath}">
<Expand count="1">C:\Folder${Target}</Expand>
<Expand count="2">C:\FolderB</Expand>
</DictionaryEx>
echo 表示の内容:
Set g = new LazyDictionaryClass
Assert  g("${USERPROFILE}\Desktop") = "C:\Users\user1\Desktop"
OSの環境変数を参照することもできます。
g("${RootPath}") = "C:\Folder${Target}"
g("${Target}") = "A"

Assert  g.Formula("${RootPath}") = "C:\Folder${Target}"
Assert  g("${RootPath}") = "C:\FolderA"
遅延評価する前の値を参照するには、Formula プロパティを使います。
関連
Set a = new LazyDictionaryClass
Set b = new LazyDictionaryClass
a.AddDictionary  b
Set g = new LazyDictionaryClass
g("${A}") = "AAA"
g("${B}") = "BB"
Assert  g.EvaluateReverse( "1AAA2BB3AAA4" ) = "1${A}2${B}3${A}4"
Set g = new LazyDictionaryClass
g("${A3}") = "AAA"
g("${A4}") = "AAAA"
g("${A2}") = "AA"
Assert  g.EvaluateReverse( "AAAA" ) = "${A4}"
値の文字列の長さが長い変数に優先的に変換されます。
逆に、変数でない ${ を含む文字列を、${ 〜 } 変数を変換しようとする文字列に入れる場合は、
次の変換をします。
'// "$\" => "$\\", "${" => "$\{"
text = Replace( Replace( text, "$\", "$\\" ), "${", "$\{" )
Set g = new LazyDictionaryClass
echo  g(text)
関連
EvaluateReverse
Set g = new LazyDictionaryClass
g("${XA}") = "X:\FolderA"
g("${Extension}") = ".txt"
Assert  g.GetStepPath( "X:\FolderA\File.xml", "X:\" ) = "${XA}\File.xml"
Assert  g.GetStepPath( "C:\FolderA\File.xml", "C:\FolderA" ) = "File.xml"
Assert  g.GetStepPath( "C:\FolderA\File.txt", "C:\FolderA" ) = "File${Extension}"
GetStepPath
GetStepPath メソッドでは、フル パスが格納された変数に戻らなかったときだけ、
指定した基準パスからの相対パスに変換されます。
${> } 形式の記述は、次の関数でも使われています。
特殊な URL 予約文字をエスケープしない
${>#} で、# をファイル名の一部にする
参考
ちなみに、戻した変数を一覧するときは、指定する
正規表現
を、
\$\{.*\}
ではなく、
\$\{[^\}]*\}
にします。 複数の変数があるときでも正しく処理するようになります。
XML の Variable タグを変数にした辞書を返します
パスに関する変数か定義された辞書を返します
${ } を使った式を解析します
でも変数を一覧することができます。
g("${RootPath}") = "C:\Folder\A"
g("${Target}") = "A"

Assert  g.Formula("${RootPath}") =  "C:\Folder\A"
Assert  g.Formula("${RootPath}") <> "C:\Folder\${Target}"
と異なり、変数の値に一致しても、変数に戻ることはありません。
<Variable  name="${FullPath1}"  value="..\File.txt"  type="FullPathType"/>
XML の Variable タグの type 属性は、Type_ プロパティで参照できます。
    path = t("C:\Folder")+"\Sub\Setting.xml"
    base_path = GetParentFullPath( path )
    Set root = LoadXML( path, Empty )

    Set g = LoadVariableInXML( root, path )

    Assert  g.Formula("${FullPath1}") = t("C:\Folder")+"\ABC"
    Assert  g.Formula("${StepPath}")  = "..\ABC"
    Assert  g.Formula("${ABC}")       = "ABC"
    Assert  g.Formula("${FullPath2}") = "${FullPath1}\File.txt"
    Assert  g.Formula("${FullPath3}") = t("C:\Folder")+"\Sub\${StepPath}\File.txt"

    Set file = OpenForWrite( "_out.xml",  g_VBS_Lib.UTF_8 )
    file.WriteLine  "<?xml version=""1.0"" encoding=""UTF-8""?>"
    file.WriteLine  "<Root>"
    file.WriteLine  ""

    For Each  variable_name  In  Array( _
            "${FullPath1}", "${StepPath}", "${ABC}", "${FullPath2}", "${FullPath3}" )
        If not IsFullPath( g.Formula( variable_name ) ) Then
            file.WriteLine  "<Variable  name="""+ variable_name +"""  value="""+ _
                g.Formula( variable_name ) +"""/>"
        Else
            file.WriteLine  "<Variable  name="""+ variable_name +"""  value="""+ _
                GetStepPath( g.Formula( variable_name ),  base_path ) + _
                """  type=""FullPathType""/>"
        End If
    Next
    file.WriteLine  ""
    file.WriteLine  "</Root>"
    file = Empty
file.WriteLine  "<Variable  name=""${FullPath1}""  value="""+ _
    g.Formula( "${FullPath1}" ) +"""  type="""+ g.Type_( "${FullPath1}" ) +"""/>"
サンプル
FullPathType
<?xml version="1.0" encoding="UTF-8"?>
<Root>

<Variable  name="${FullPath1}"  value="..\ABC"  type="FullPathType"/>
<Variable  name="${StepPath}"  value="..\ABC"/>
<Variable  name="${ABC}"  value="ABC"/>
<Variable  name="${FullPath2}"  value="${FullPath1}\File.txt"/>
<Variable  name="${FullPath3}"  value="${StepPath}\File.txt"  type="FullPathType"/>

</Root>
サンプル
g("${F1}") = "C:\Folder1"
g("${F2}") = "C:\Folder2"
Assert  g.GetFullPath( "File.txt", "C:\Folder1" ) = "C:\Folder1\File.txt"
Assert  g.GetFullPath( "File.txt", "${F1}" ) = "C:\Folder1\File.txt"
Assert  g.GetFullPath( "${F2}\File.txt", "${F1}" ) = "C:\Folder2\File.txt"
Assert  g.GetFullPath( "File.txt", "${No}" )  '// Error
参考
→ Python - 数列 (range クラス)
Assert  g("${ToCSV( %d, 1, 3 )}") = "1, 2, 3"
Assert  g("${ToCSV( %d, 2, 5 )}") = "2, 3, 4, 5"
Assert  g("${ToCSV( %d, 2, 5 )}") = "5, 4, 3, 2"
Assert  g("${ToCSV( %02d, 1, 3 )}") = "01, 02, 03"

g("${N}") = "Num"
Assert  g("${ToCSV( ${N} = %d, 1, 3 )}") = "Num = 1, Num = 2, Num = 3"
Assert  g("${N} = ${ToCSV( %d, 1, 3 )}") = "Num = 1, 2, 3"
→ T_LazyDictionary.vbs
T_LazyDictionaryCSV
テスト
( ) の中のパラメーターは、
、開始の値、最後の値です。
C言語の printf 書式の中に、${ } 変数を記述できます。
( ) の中のパラメーターは、CSV としてパースされるので、" "で囲むこともできます。
Sub  Main()
    Set g = new LazyDictionaryClass

    Set g("${GetObject()}") = GetRef( "My_GetObject" )
    Set object = g("${GetObject( a,b )}")
    Assert  object.Name = " a,b "

    Set g("${UpperCase()}") = GetRef( "My_UpperCase" )
    g.Delegate = "UserDefined"
    Assert  g("before  ${Upper( a,b )}  after") = _
        "before  ( A,B )  after"
End Sub

Function  My_GetObject( ref_Dictionary,  in_FunctionName,  in_Parameter )
    Set  object = new NameOnlyClass
    object.Name = in_Parameter
    Set My_GetObject = object
End Function

Function  My_UpperCase( ref_Dictionary,  in_FunctionName,  in_Parameter )
    Assert  in_FunctionName = "${My_UpperCase()}"
    Assert  ref_Dictionary.Delegate = "UserDefined"
    My_GetObject = "("+ UCase( in_Parameter ) +")"
End Function
Function  LazyDictionaryFunction( ref_Dictionary as LazyDictionaryClass,
    in_FunctionName as string,  in_Parameter as string ) as Variant
関数は下記の型である必要があります。
LazyDictionaryClass で ${Function( parameters )} 形式を指定したときに呼び出す関数の型。
【引数】
ref_Dictionary
in_Parameter
LazyDictionaryClass のオブジェクト
括弧の中のすべてのパラメーター
Set g("${UpperCase()}") = GetRef( "UpperCase" )
コールバックする関数を設定するには、次のように記述します。
サンプル
${Function( parameters )} 形式を指定すると、アプリケーションが定義した関数を呼び出す、
または、VBScript で定義した関数をコールバックさせることができます。
Assert  g("${UpperCase( abc, def )}") = "ABC, DEF"
UpperCase 関数をパラメーター abc, def で呼び出し、ABC, DEF が返されたことをチェックする
には、次のように記述します。
in_Parameter の中にあるそれぞれのパラメーターを取得するときは、
などを使ってください。
${Function( parameters )} を置き換えた後の値
返り値
in_FunctionName
関数名。 例:"${FunctionName()}"
ref_Dictionary の Delegate メンバー変数は、LazyDictionaryClass オブジェクトを生成
したユーザーが設定して、コールバック関数で参照することができます。
Type_
type
関連
は、変数の値を参照し、フル パスを返します。